Índice

  1. Introducción
  2. Normalización de los datos
  3. Preprocesamiento de los datos
  4. Frecuencia de palabras
  5. Análisis de sentimientos
  6. Análisis de los tweets más virales
  7. Anáisis de #hashtags más virales
  8. Grafo de usuarios del dataset
  9. Análisis de comunidades
  10. Conclusiones

1. Introducción

Popularmente conocida como la “Ley Trans”, es uno de los proyectos más controvertidos del gobierno de coalición de izquierda. Incluso dentro de la coalición hay opiniones opuestas. Si se aprueba el proyecto de ley, España se convertiría en el país más grande de Europa en permitir que las personas cambien legalmente el nombre y género en sus documentos de identidad sin la necesidad de años de terapia hormonal o diagnóstico médico. Esto ha provocado un gran debate y/o fuertes posicionamientos al respecto, lo que también se ha reflejado en redes sociales como Twitter.

En este documento se van a analizar 14.1 millones de tweets del 13/01/2021 al 12/10/2022 en relación a la https://www.boe.es/buscar/doc.php?id=BOE-A-2023-5366. El dataset contiene más de 14 millones de tweets, con 257.000 usuarios y 738.651 aristas (respuestas entre usuarios).

1.1. Importar librerías

# Importaciones de las librerias que utilizaremos
library(quanteda)
## Package version: 4.0.2
## Unicode version: 15.1
## ICU version: 74.2
## Parallel computing: 16 of 16 threads used.
## See https://quanteda.io for tutorials and examples.
library(quanteda.textplots)
library(stringr)
library(wordcloud2)
library(tm)
## Loading required package: NLP
## 
## Attaching package: 'NLP'
## The following objects are masked from 'package:quanteda':
## 
##     meta, meta<-
## 
## Attaching package: 'tm'
## The following object is masked from 'package:quanteda':
## 
##     stopwords
library(tidytext)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ purrr     1.0.2
## ✔ forcats   1.0.0     ✔ readr     2.1.5
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ purrr::%||%()       masks base::%||%()
## ✖ ggplot2::annotate() masks NLP::annotate()
## ✖ dplyr::filter()     masks stats::filter()
## ✖ dplyr::lag()        masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(syuzhet)
library(dplyr)
library(textdata)
library(ggplot2)
library(htmlwidgets)
library(igraph)
## 
## Attaching package: 'igraph'
## 
## The following objects are masked from 'package:lubridate':
## 
##     %--%, union
## 
## The following objects are masked from 'package:dplyr':
## 
##     as_data_frame, groups, union
## 
## The following objects are masked from 'package:purrr':
## 
##     compose, simplify
## 
## The following object is masked from 'package:tidyr':
## 
##     crossing
## 
## The following object is masked from 'package:tibble':
## 
##     as_data_frame
## 
## The following object is masked from 'package:quanteda.textplots':
## 
##     as.igraph
## 
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## 
## The following object is masked from 'package:base':
## 
##     union

1.2. Establecer el directorio de trabajo

# Establecer directorio de trabajo
setwd("/home/antonio/Repos/ley-trans")

1.3. Cargar el dataset

El dataset es de Kaggle y se puede encontrar en el siguiente enlace: https://www.kaggle.com/datasets/hectorfr1984/spanish-trans-law-twitter-dataset

df <- data.frame()
dataset_csv <- read.csv("spanish-trans-law-twitter-dataset.csv", header = TRUE, sep = ",", fill = TRUE)
## Warning in scan(file = file, what = what, sep = sep, quote = quote, dec = dec,
## : embedded nul(s) found in input
df <- rbind(dataset_csv, df)

Guardamos el dataset en un archivo rda para poder trabajar con él más adelante.

# Guardamos el data frame en un archivo rda
save(df, file = "df.rda")

2. Normalización de los datos

El dataset no está normalizado, ya que en cada fila tenemos información de los usuarios la cual debería estar en una tabla aparte, por lo tanto vamos a separar el dataframe en dos dataframes de usuarios y tweets.

2.1. Daframe de usuarios

El dataframe de usuarios tendrá los siguientes campos: user_id, user_screen_name, user_description, user_created_at_iso, user_followers y user_friends.

df_usuarios <- df %>% 
  select(user_id, user_screen_name, user_description, user_created_at_iso, user_followers, user_friends) %>% 
  distinct()

Los followers y friends van variando en función del tiempo, por lo tanto para no tener filas repetidas, usaremos el máximo de followers y friends de cada usuario.

df_usuarios <- df_usuarios %>%
  group_by(user_id) %>%
  summarise(user_screen_name = first(user_screen_name),
            user_description = first(user_description),
            user_created_at_iso = first(user_created_at_iso),
            user_followers = max(user_followers),
            user_friends = max(user_friends))

También normalizaremos la fecha de creación de los usuarios.

df_usuarios$user_created_at_iso <- as.POSIXct(df_usuarios$user_created_at_iso, format="%Y-%m-%d")

Guardamos el dataframe de usuarios en un archivo rda.

# Guardamos el data frame en un archivo rda
save(df_usuarios, file = "df_usuarios.rda")

El dataframe de usuarios tendrá los siguientes campos: tweet_id, in_reply_to_user_id, user_id, retweet_id, retweet_user_id, tweet_created_at_iso, tweet_full_text.

df_tweets <- df %>% 
  select(tweet_id, in_reply_to_user_id, user_id, retweet_id, retweet_user_id, tweet_created_at_iso, tweet_full_text) %>% 
  distinct()

Guardamos el dataframe de tweets en un archivo rda.

# Guardamos el data frame en un archivo rda
save(df_tweets, file = "df_tweets.rda")

3. Preprocesamiento de los datos

Crearemos un nuevo dataframe df_filtered con el contenido de los tweets filtrado.

df_filtered <- df_tweets

3.1. Normalizar las fechas

Para poder trabajar con las fechas, vamos a convertirlas a formato POSIXct

df_filtered$tweet_created_at_iso <- as.POSIXct(df_filtered$tweet_created_at_iso, format="%Y-%m-%d")

3.2. Pasar los tweets a minúsculas

Es necesario pasar los tweets a minúsculas para evitar que palabras iguales pero escritas de forma diferente se consideren diferentes.

#Convertimos todas las letras a minúsculas
df_filtered$tweet_full_text <- tolower(df_filtered$tweet_full_text)

3.3. Eliminar stopwords

Las stopwords son palabras que no aportan significado al texto, como artículos, preposiciones, etc. Vamos a eliminarlas de los tweets.

# Eliminar las stopwords del español
df_filtered$tweet_full_text <- removeWords(df_filtered$tweet_full_text, stopwords("es"))

Se ha observado que es muy popular en los tweets el uso de stopwords acortadas, como “q” en lugar de “que”, “x” en lugar de “por”, etc. Por lo tanto, eliminaremos las palabras de una sola letra.

# Eliminar las palabras de una sola letra
df_filtered$tweet_full_text <- str_replace_all(df_filtered$tweet_full_text, "\\b[a-zA-Z]\\b", "")

3.4. Eliminar URLs, números, caracteres especiales y palabras no deseadas

Eliminamos las URLs de los tweets.

# Eliminar urls
df_filtered$tweet_full_text <- str_replace_all(df_filtered$tweet_full_text, "https?://([^/\\s]++)\\S*+|http?://([^/\\s]++)\\S*+", "")

Eliminamos los números y los caracteres especiales.

# Eliminar los números y los carácteres especiales
df_filtered$tweet_full_text <- str_replace_all(df_filtered$tweet_full_text, "[^[:alpha:][:space:]]", "")

Por último eliminamos las palabras que no sean de nuestro interés. Las palabras “ley” y “trans” son redundantes ya que todos los tweets van en relación a ese mismo tema. La palabra “si” es muy común en los tweets y no aporta información relevante, y “rt” es la abreviatura de “retweet”.

# Eliminar palabras que no sean de nuestro interés
palabras_eliminar = c("ley", "trans", "leytrans", "rt", "si")
df_filtered$tweet_full_text <- removeWords(df_filtered$tweet_full_text, palabras_eliminar)

3.5. Eliminar hashtags, menciones y retweets

# Eliminar los hashtags, menciones y retweets
df_filtered$tweet_full_text <- str_replace_all(df_filtered$tweet_full_text, "#\\S+", "")
df_filtered$tweet_full_text <- str_replace_all(df_filtered$tweet_full_text, "@\\S+", "")
df_filtered <- df_filtered[!grepl("^RT", df_filtered$tweet_full_text),]

3.6. Guardar el dataset filtrado

# Guardamos el data frame en un archivo r### 4. Frecuencia de palabras <a name="frecuencia"></a>da
save(df_filtered, file = "df_filtered.rda")

4. Frecuencia de palabras

4.1. Crear matriz de frecuencia de palabras

4.1.1. Crear corpus y tokens

Creamos el corpus de los tweets, que como ya se ha mencionado, es un conjunto de documentos de texto.

# Crear un corpus con los tweets
corpus_tweets <- corpus(df_filtered$tweet_full_text)

Creamos los tokens, que son las palabras que componen los documentoss. Indicamos que queremos eliminar los números, los signos de puntuación, los símbolos, los separadores y las URLs.

# Generamos los tokens
token_tweets <-quanteda::tokens(corpus_tweets,
                              what = "word",
                              remove_numbers = TRUE,
                              remove_punct = TRUE,
                              remove_symbols = TRUE,
                              remove_separators = TRUE,
                              remove_url = TRUE)
4.1.2. Crear matriz de frecuencia
# Generamos la matriz de frecuencia de los tweets
matrix_tweets <-dfm(token_tweets)

4.2. Barplot de las 10 palabras más frecuentes

Primero sacamos las 10 palabras más frecuentes con la ayuda de nuestra matriz de frecuencia.

# Mostramos las 10 palabras más frecuentes
top_10 <- topfeatures(matrix_tweets, 10)
top_10
##     personas      mujeres     derechos         psoe          hoy       género 
##       148102       107116        96472        95393        93510        90521 
## irenemontero         años        lgtbi          ser 
##        71705        65588        65289        64994

Pasamos el objeto top_10 a un data frame para poder hacer el gráfico.

# Convertimos el objeto top_10 a un data frame
top_10_df <- data.frame(palabra = names(top_10), frecuencia = as.numeric(top_10))

Creamos el gráfico de barras con las 10 palabras más frecuentes.

# Barplot
barplt <- ggplot(top_10_df, aes(x = reorder(palabra, frecuencia), y = frecuencia)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  theme_minimal() +
  labs(
       x = "Palabra",
       y = "Frecuencia")

barplt

Por último, guardamos el gráfico de barras.

# Guardamos el gráfico
ggsave("barplot.png", plot = barplt, width = 10, height = 5, units = "in")

4.3. Wordcloud de las palabras más frecuentes

4.3.1 Wordcloud normal

En este caso sacaremos las 100 palabras más frecuentes y las pasamos a data frame.

# Hacemos el dataframe del top 100
top_100 <- topfeatures(matrix_tweets, 100)
top_100_df <- data.frame(palabra = names(top_100), frecuencia = as.numeric(top_100))

Creamos el wordcloud con las 100 palabras más frecuentes. Ajustamos los parametros minRotation y maxRotation y rotateRatio para darle un aspecto más atractivo.

# Wordcloud
worldcloud_palabras <- wordcloud2(top_100_df, size = 1.0 , minRotation = -pi/6, maxRotation = -pi/6, rotateRatio = 1)
worldcloud_palabras

En el wordcloud la palabra más predominante es personas, ya que se usa mucho “personas trans”; lo mismo pasa con mujeres (“mujeres trans”). También podemos encontrar los 4 pártidos políticos más importantes de España: PSOE, PP, Vox y Podemos. Destaca también la palabra “menores” que va en relación a las críticas de la ley por parte de los detractores. Otras palabras en relación al tema son género, sexo y lgtpi.

Guardamos el wordcloud. Solo se guardará el html, ya que el wordcloud2 no se puede guardar en formato png.

# Guardar el wordcloud
htmlwidgets::saveWidget(worldcloud_palabras, "wordcloud_palabras.html", selfcontained = TRUE)
4.3.2 Wordcloud de bigramas

Generamos los bigramas.

# Generamos los bigramas
bigramas <- tokens_ngrams(token_tweets, n = 2)

Creamos la matriz de frecuencia de los bigramas.

# Generamos la matriz de frecuencia de los bigramas
matrix_bigramas <- dfm(bigramas)

Sacamos las 100 palabras más frecuentes de los bigramas.

top_100 <- topfeatures(matrix_bigramas, 100)
top_100_df <- data.frame(palabra = names(top_100), frecuencia = as.numeric(top_100))

Creamos el wordcloud de los bigramas.

# Wordcloud
worldcloud_palabras_bigramas <- wordcloud2(top_100_df, size = 1.0 , minRotation = -pi/6, maxRotation = -pi/6, rotateRatio = 1)

wordcloud_bigramas En el caso de los bigramas figuras políticas como Irene Montero (ex-ministra de igualdad) y Carmen Calvo (actual presidenta del Consejo de Estado). Otras palabras en relación al tema son “identidad genero”, “autodeterminación genero” y “derechos personas”. En general aparecen muchos bigramas con la palabra derechos, lo cual puede indicar que la ley se ve como un avance en los derechos de las personas.

Lo guardamos.

# Guardar el wordcloud
htmlwidgets::saveWidget(worldcloud_palabras_bigramas, "wordcloud_bigramas.html", selfcontained = TRUE)

5. Análisis de sentimientos

El análisis de sentimientos es una técnica que consiste en determinar si un texto es positivo, negativo o neutro. Para ello, se asigna un valor numérico a cada palabra del texto mediante un diccionario sentimental. En nuestro caso, al ser un dataset en español, no existen muchos diccionarios sentimentales, por lo que utilizaremos la función get_sentiment del paquete syuzhet, la cual primero traduce la palabra al inglés y luego le asigna un valor sentimental.

5.1. Crear diccionario sentimental

Primero creamos un tidyset con los tweets.

# Creamos un tidyset con los tweets
tidy <- df_filtered %>% 
  unnest_tokens(word, tweet_full_text)

Para ahorrarnos tiempo de computo, vamos a generar un diccionario sentimental con todas las palabras del dataset.

# Creamos un diccionario sentimental con todas las palabras del dataset usando la función get_sentiment(word, method = "nrc", lang="spanish")
sentiment_dict <- tidy %>%
  distinct(word) %>%
  mutate(sentiment = get_sentiment(word, method = "nrc", lang="spanish"))

Agregaremos algunas palabras customizadas que el diccionario sentimental no ha detectado.

palabras_añadir = c("facha","nazi","racista",
                    "racistas","nazis","gilipollas",
                    "sanchista","sanchistas","maricones",
                    "alertafeminista","fachas","vertederofacha",
                    "neonazis","neonazi","feminazis",
                    "terfisfeminazi","transfobo","machista",
                    "machismo","sexta","transfobia",
                    "terf","terfs","terfas",
                    "retrograda","transexcluyente","transexcluyentes",
                    "feminazi","fachasnazis","maricas",
                    "machirulo","perro","derrogación",
                    "dictador","franco","fascista",
                    "progre","retroceso","podemita",
                    "podemitas","retrogrado","homófobo",
                    "homófobos","homófobas","homofobia",
                    "rojo", "rojos","puto",
                    "putos", "bulo","bulos",
                    "comunista","comunistas","violador",
                    "violadores","patriarcado","patriarcal",
                    "maricón","comunismo","socialcomunista",
                    "pitorreo","terfachas","travelo")

# Si la palabra ya está recogida, cambiamos su valor sentimental a -3
new_sentiment_dict <- sentiment_dict %>%
  mutate(sentiment = ifelse(word %in% palabras_añadir, -3, sentiment))

# Si la palabra no está recogida, la añadimos con valor sentimental -3
new_sentiment_dict <- new_sentiment_dict %>%
  anti_join(data.frame(word = palabras_añadir), by = "word") %>%
  bind_rows(data.frame(word = palabras_añadir, sentiment = -3))

5.2. Calcular sentimiento de los tweets

Una vez tenemos el diccionario sentimental, calculamos el sentimiento de cada tweet.

# Ahora a cada tweet le añadimos el sentimiento
tweets_sentiment <- tidy %>%
  inner_join(new_sentiment_dict, by = "word") %>%
  group_by(tweet_id) %>%
  summarise(sentiment = sum(sentiment))

5.3. Histograma de la cantidad de tweets por sentimiento

Mostramos el histograma de los sentimientos.

ggplot(data = tweets_sentiment, aes(x = sentiment)) + 
  geom_bar(color = 'darkslategray', fill = 'steelblue') + 
  xlab("Sentimiento") + 
  ylab("Cantidad de Tweets") + 
  ggtitle("Gráfico sentimiento")

# Guardamos el gráfico
ggsave("sentiment.png", plot = last_plot(), width = 10, height = 5, units = "in")

Por último, calculamos el porcentaje de tweets positivos, negativos y neutros.

# Calcular porcentaje de tweets positivos, negativos y neutros
tweets_sentiment %>%
  summarise(
    positivos = sum(sentiment > 0) / n() * 100,
    negativos = sum(sentiment < 0) / n() * 100,
    neutros = sum(sentiment == 0) / n() * 100
  )
## # A tibble: 1 × 3
##   positivos negativos neutros
##       <dbl>     <dbl>   <dbl>
## 1      34.9      29.1    36.0

Vemos que en general los tres tipos de sentimientos están bastante equilibrados, aunque predominan los neutros y entre los positivos y negativos ganan los positivos. Que haya más sentimiento positivo en relación a la ley puede indicar que en general hay mas apoyo que detractores de la ley.

5.4. Gráfico de sentimiento en el tiempo

Generaremos el gráfico del sentimiento en el tiempo con ambos diccionarios para comprobar si las palabras añadidas han afectado al sentimiento de los tweets.

5.4.1. Gráfico de sentimiento en el tiempo con diccionario modificado

Primero, creamos un dataframe con la fecha y el sentimiento de cada tweet.

# Creamos un dataframe con la fecha y el sentimiento de cada tweet
df_sentimiento <- df_filtered %>%
  inner_join(tweets_sentiment, by = "tweet_id") %>%
  select(tweet_created_at_iso, sentiment)

Creamos un gráfico de sentimiento en el tiempo.

# Gráfico de sentimiento en el tiempo
ggplot(data = df_sentimiento,
       aes(x = tweet_created_at_iso,
           y = sentiment
          )) + 
  geom_smooth(color = 'darkslategray') + 
  xlab("Fecha") + 
  ylab("Sentimiento") + 
  scale_x_datetime(date_labels = "%b", date_breaks = "1 month") +
  ggtitle("Gráfico de sentimiento en el tiempo")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

El 10 de marzo de 2021 comenzo la huelga de hambre de Mar Cambrolle la cual ya ha sido mencionada en el análisis de hashtags. A partir de esa fecha, el sentimiento positivo a ido creciendo. El 17 de marzo de ese mismo año se registró la Proposición de Ley para la igualdad real y efectiva de las personas trans en el Congreso de los Diputados, lo que puede haber influido en el sentimiento positivo. El 18 de mayo se votó por la admisión de la ley, la cual fue rechazada debido a los votos de PP, Vox y por la abstención del PSOE.

El 29 de junio de 2021, el ministerio de igualdad presentó el anteproyecto de ley, en el que se incluía la autodeterminación de género para mayores de 16 años, y la eliminación de la necesidad de diagnóstico médico para cambiar el género en el DNI. A partir de la presentación del anteproyecto, se observa un mínimo que por primera vez es negativo en el gráfico. Puede deverse a que cuando ses presentó el anteproyecto, se incluyeron medidas que no gustaron a los detractores de la ley.

En junio de 2022 se observa un gran pico de positividad, se puede deber a que el 27 de junio de 2022 el documento de anteproyecto fue aprobado, pasando a ser un proyecto de ley. Luego, vemos un gran descenso en la positividad, que puede deberse a la perdida del gran interés inicial de la izquierda y a las críticas de los retractores.

El 8 de septiembre se anunció que se reducirían la mitad de los plazos de la ley, lo cual haría que se aprobase ante la ley. Justo en este periodo comienza a subir la positividad, lo cual puede deberse a que la ley finalmente se aprobará.

5.4.2. Gráfico de sentimiento en el tiempo con diccionario sin modificar

Si lo comparemos con el gráfico generado usando el diccionario sin modificar, vemos que las palabras customizadas han afectado notablemente al sentimiento de los tweets.

tweets_sentiment_old <- tidy %>%
  inner_join(sentiment_dict, by = "word") %>%
  group_by(tweet_id) %>%
  summarise(sentiment = sum(sentiment))

df_sentimiento_old <- df_filtered %>%
  inner_join(tweets_sentiment_old, by = "tweet_id") %>%
  select(tweet_created_at_iso, sentiment)

ggplot(data = df_sentimiento_old,
       aes(x = tweet_created_at_iso,
           y = sentiment
          )) + 
  geom_smooth(color = 'darkslategray') + 
  xlab("Fecha") + 
  ylab("Sentimiento") + 
  scale_x_datetime(date_labels = "%b", date_breaks = "1 month") +
  ggtitle("Gráfico de sentimiento en el tiempo")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

6. Análisis de los tweets más virales

Primero sacaremos los tweets más virales, es decir, los tweets con más respuestas. Para ello agruparemos los tweets por la columna in_reply_to_user_id, que indica el id del tweet al que se responde, y contaremos cuántas respuestas tiene cada tweet.

tweets_virales <- df_tweets %>%
  group_by(retweet_id) %>%
  summarise(retweets = n()) %>%
  arrange(desc(retweets))

El tweet más viral saldra como NA ya que la mayoría te tweets no son en respuesta a otros, por lo tanto eliminaremos ese tweet.

tweets_virales <- tweets_virales[-1,]
tweets_virales
## # A tibble: 78,845 × 2
##    retweet_id retweets
##         <dbl>    <int>
##  1    1.47e18     5119
##  2    1.40e18     4835
##  3    1.58e18     4391
##  4    1.36e18     4049
##  5    1.44e18     3596
##  6    1.54e18     3441
##  7    1.36e18     3395
##  8    1.58e18     3294
##  9    1.56e18     3238
## 10    1.36e18     3138
## # ℹ 78,835 more rows

Crearemos una función para ver el n-ésimo tweet más viral.

ver_tweet_viral <- function(n) {
  tweet_viral_id <- tweets_virales$retweet_id[n]
  tweet <- subset(df_tweets, tweet_id == tweet_viral_id)
  user <- subset(df_usuarios, user_id == tweet$user_id)
  
# Mostramos la información del tweet
cat(sprintf("Retweets: %d\nUsuario: %s\nDescripción:%s\nContenido:%s",
            tweets_virales$retweets[n], user$user_screen_name,
            user$user_description, tweet$tweet_full_text))
}

El tweet con mayor número de retweets (5119) es a favor de la ley, y es del presidente de Más Madrid, @EduardoFRub. El número de retweets puede parecer bajo, pero esto se debe a que el dataset no recoge todos los retweets de cada tweet.

ver_tweet_viral(1)
## Retweets: 5119
## Usuario: EduardoFRub
## Descripción:Senador de Más Madrid y Diputado de la Asamblea de Madrid. Derechos LGTB+  🙋🏻‍♂️IG: @eduardo_rubino
## Contenido:🔴 Pues ya tenemos noticia de última hora:
## La propuesta de derogación completa de la Ley LGTBI y la Ley Trans de la Comunidad de Madrid irá a pleno el día 16 de diciembre.
## 
## Sería el primer retroceso en legislación LGTBI en España desde la democracia.

El segundo tweet más viral (4835), va en contra de la ley y es de una usuaria canaria con 3641 followers. En el tweet, se queja de que la comunidad de canarias haya aprobado la ley.

ver_tweet_viral(2)
## Retweets: 4835
## Usuario: garaS87
## Descripción:Canaria. Feminista. Roja perdida. Foto portada: @digital_GC
## Contenido:Canarias que prohibió los toros, que dijo NO a la OTAN, que no ha elegido en su parlamento a ni un solo representante del odio de la extrema derecha está a pocas horas de aprobar su Ley Trans. Un gran pueblo.

El tercer tweet más viral, es de Irene Montero, ex ministra de Igualdad. Se trata de un hilo desmintiendo bulos de la ley trans.

ver_tweet_viral(3)
## Retweets: 4391
## Usuario: IreneMontero
## Descripción:Psicóloga, madre, #Feminista. Ministra de @IgualdadGob del Gobierno de España. Yo por ellas, madre, y ellas por mí.
## Contenido:Desmontando los bulos de la transfobia. La Ley Trans será ley 👇 https://t.co/82utDQk5Lo

7. Anáisis de #hashtags más virales

Los hashtags son una forma de categorizar los tweets y de hacer que estos sean más visibles. Nos pueden ayudar a conocer los temas más populares sobre la ley.

Sacamos los hashtags más virales.

hashtags_virales <- df_tweets %>%
  filter(str_detect(tweet_full_text, "#")) %>%
  mutate(hashtags = str_extract_all(tweet_full_text, "#\\w+")) %>%
  unnest(hashtags) %>%
  group_by(hashtags) %>%
  summarise(tweets = n()) %>%
  arrange(desc(tweets))

Visualizamos los hashtags más virales.

hashtags_virales
## # A tibble: 15,552 × 2
##    hashtags             tweets
##    <chr>                 <int>
##  1 #LeyTrans             81817
##  2 #HabraLeyTrans        10278
##  3 #LeyTransYa            7938
##  4 #leytrans              7797
##  5 #HabráLeyTrans         7237
##  6 #LeyTransAlCongreso    6004
##  7 #HuelgaDeHambreTrans   5474
##  8 #trans                 4282
##  9 #CMin                  3763
## 10 #LeyTransEstatal       3534
## # ℹ 15,542 more rows

7.1. Análisis del hashtag #HuelgaDeHambreTrans

El primer hastag interesante es el de #HuelgaDeHambreTrans, veamos de que trata este sentimiento.

Sacamos tweets con el hashtag #HuelgaDeHambreTrans.

df_tweets_huelga <- df_tweets %>%
  filter(str_detect(tweet_full_text, "#HuelgaDeHambreTrans"))

# Añadimos el número de retweets a los tweets
df_tweets_huelga <- tweets_virales %>%
  inner_join(df_tweets_huelga, by = c("retweet_id" = "tweet_id"))

# Los ordenamos por número de retweets
df_tweets_huelga <- df_tweets_huelga[order(-df_tweets_huelga$retweets),]

Para ver los tweets definiremos una función rápido para ver tweets.

ver_tweet <- function(n) {
  tweet <- df_tweets_huelga[n,]
  user <- subset(df_usuarios, user_id == tweet$user_id)
  
  # Mostramos la información del tweet
  cat(sprintf("Usuario: %s\nDescripción:%s\nContenido:%s\nRetweets: %i", user$user_screen_name, user$user_description, tweet$tweet_full_text, tweet$retweets))
}

Leeamos un tweet cualquiera con el hashtag #HuelgaDeHambreTrans.

El primer tweet no va en relación a la huelga, es de una mujer trans que comenta como el partido feminista ha convocado un encuentro anti trans. El grupo de feministas en contra de las personas trans es conocido como TERF, pero en español se utiliza más el termino peroyativo “terfas”. Estas feministas consideran que las mujeres trans, al haber nacido hombres, no pueden ser consideradas mujeres y que son “hombres infiltrados”.

ver_tweet(1)
## Usuario: elsaruizcomica
## Descripción:•Mujer trans (ella/her) •Cómica, ilustradora y youtuber. •Contacto: elsaruiz@reclutados.es
## Contenido:Mientras activistas trans y familiares hacen #HuelgaDeHambreTrans por nuestros derechos el Partido Feminista organiza un encuentro anti #LeyTrans con la Ministra Robles y una portavoz de Hazte Oír. 🤦
## Ánimo y gracias compañeres. ❤️
## #LeyTransAlCongreso https://t.co/3xqpz0PWNt
## Retweets: 640

El segundo tweet más viral de #HuelgaDeHambreTrans explica que la huelga trans se debe al bloqueo de la ley impuesto por el PSOE.

ver_tweet(2)
## Usuario: PlataformaTrans
## Descripción:Federación Plataforma Trans 
## #TransEmpowerment  
## usurpar la voz de las personas trans en discursos o actividades de visibilidad trans, es #IntruCISmo!!
## Contenido:🔴@CambrolleMar junto con más de 70 activistas trans y madres de todo Estado Español comienzan HUELGA DE HAMBRE INDEFINIDA hasta que bloque investidura dé registro a#LeyTrans en @Congreso_Es para vencer bloqueo de @PSOE #HuelgaDeHambreTrans #LeyTransAlCongreso #HabráLeyTrans https://t.co/YjFw1k0AvM
## Retweets: 465

Veamos el último tweet en relación al hashtag #HuelgaDeHambreTrans. La activista trans Mar Cambrolle, cuenta que la huelga será de 3 días y que se quieren conseguir reconocer un derecho humano.

ver_tweet(4)
## Usuario: CambrolleMar
## Descripción:🏳️‍🌈 Activista por los DD.HH del Colectivo LGTBI, Presidenta de ATA-Sylvia Rivera, de Federación Plataforma Trans y Portavoz en Europa de RESPETTTRANS 🏳️‍⚧️
## Contenido:3 día #HuelgaDeHambreTrans personas trans siempre tenemos que exponer nuestras vidas para mendigar igualdad pero también siempre cualquier derecho humano reconocido es una victoria indiscutible para toda la humanidad por eso #HabraLeyTrans #LeyTransAlCongreso https://t.co/UeT7Vcr1ra
## Retweets: 235

7.2. Análisis del hashtag #LeyTransYa

Ahora veamos uno de los hashtags a favor de la ley, #LeyTransYa.

Sacamos tweets con el hashtag #LeyTransYa.

df_tweets_ley <- df_tweets %>%
  filter(str_detect(tweet_full_text, "#LeyTransYa"))

# Añadimos el número de retweets a los tweets
df_tweets_ley <- tweets_virales %>%
  inner_join(df_tweets_ley, by = c("retweet_id" = "tweet_id"))

# Los ordenamos por número de retweets
df_tweets_ley <- df_tweets_ley[order(-df_tweets_ley$retweets),]

ver_tweet_ley <- function(n) {
  tweet <- df_tweets_ley[n,]
  user <- subset(df_usuarios, user_id == tweet$user_id)
  
  # Mostramos la información del tweet
  cat(sprintf("Usuario: %s\nDescripción:%s\nContenido:%s\nRetweets:%s",
   user$user_screen_name, user$user_description, tweet$tweet_full_text, tweet$retweets))
}

El primer tweet es conciso y directo, es de un usuario que pide la aprobación de la ley.

ver_tweet_ley(1)
## Usuario: ikevinarnold
## Descripción:'cause darling I'm a nightmare dressed like a daydream. Administración de empresas. A veces hago de politólogo a punto de un colapso.
## Contenido:Un pedido justo y necesario. #LeyTransYa 🏳️‍⚧️ #Pride2022 https://t.co/kKZt3iQIEV
## Retweets:1267

El siguiente tweet tiene un tono más agresivo (Stay angry, #AngryTransYouth) y da animos al colectivo a ‘cambiar las cosas’.

ver_tweet_ley(2)
## Usuario: arctic_kev
## Descripción:⚧ Kev. He/himbo. 29. Domesticated yet feral. Problematic bi. Art Director by day, activist by night. #AngryTransYouth 's creator.
## Contenido:En el #DiaVisibilidadTrans 🏳️‍⚧️ quiero recuperar el breve manual ilustrado que hice para que la gente cis ayude en nuestra lucha. La pelea no termina el 31M. Mañana seguiremos haciendo ruido. Cambiar las cosas es responsabilidad de todes. Stay angry. #LeyTransYa  #AngryTransYouth https://t.co/TeuNDuNvpe
## Retweets:569

El último tweet que veremos es de un usuario que celebra la aprobación del dictámen de la ley.

ver_tweet_ley(3)
## Usuario: CostaGino
## Descripción:
## Contenido:Celebro la aprobación del dictámen de la #LeyDeIdentidadDeGéneroYa. Ojalá se debata y apruebe pronto en el Pleno, porque luego de casi 5 años de indiferencia, la #LeyTransYa traerá igualdad y hará justicia para much@s!  🏳️‍⚧️ 🇵🇪
## Retweets:419

7.3. Análisis del hashtag #NoLeyTrans

Los 13 primeros #hastags vemos que son a favor de la ley, uno de los primeros negativos es #NoLeyTrans, veamos algunas de las opiniones en contra de la ley.

Sacamos tweets con el hashtag #NoLeyTrans.

df_tweets_no_ley <- df_tweets %>%
  filter(str_detect(tweet_full_text, "#NoLeyTrans"))

# Añadimos el número de retweets a los tweets
df_tweets_no_ley <- tweets_virales %>%
  inner_join(df_tweets_no_ley, by = c("retweet_id" = "tweet_id"))

# Los ordenamos por número de retweets
df_tweets_no_ley <- df_tweets_no_ley[order(-df_tweets_no_ley$retweets),]

ver_tweet_no_ley <- function(n) {
  tweet <- df_tweets_no_ley[n,]
  user <- subset(df_usuarios, user_id == tweet$user_id)
  
# Mostramos la información del tweet
cat(sprintf("Usuario: %s\nDescripción:%s\nContenido:%s\nRetweets:%d",
 user$user_screen_name, user$user_description, tweet$tweet_full_text, tweet$retweets))
}

Veamos un tweet en contra de la ley.

El primer tweet parace ser de otra feminista TERF, que habla de como se les va a ‘lava el cerebro a las niñas para que se crean chicos’.

ver_tweet_no_ley(1)
## Usuario: ContraBorrado
## Descripción:Sexo es la categoría biológica sobre la que se construye el sexismo. Género es la herramienta cultural de que se sirve el machismo para crear desigualdad.
## Contenido:Cuando nuestras hijas quieran dobles mastectomías porque en el colegio les dan charlas donde les dicen que son niños,
## señalaremos a @sanchezcastejon y a su ley misógina trans.
## Entre #FeminismoOTraición, Sánchez elige traición
## #NoLeyTrans https://t.co/MIffCPwANd
## Retweets:202

El segundo tweet con más retweets es de un usuario que odia a la izquierda. El tweet incita a la gente a popularizar el hashtag #NoLeyTrans para manifestar el rechazo a la ley.

ver_tweet_no_ley(2)
## Usuario: el_analista2020
## Descripción:Extremadamente capitalista y anticomunista. Mi desprecio hacia la izquierda es pasional e ilimitado. Mi único defecto es la falta de corrección política.
## Contenido:Señores congresistas:
## 
## Ustedes no puedes permitir que se apruebe esa degenerada ley Trans que algunos están promoviendo el día de hoy. 
## 
## #NOalaLeyTrans 
## #NoLeyTrans 
## 
## Hagamos viral estos hashtags y manifestemos con firmeza nuestro rechazo a esta ridícula propuesta.
## Retweets:189

El tercer tweet es de ConfluenciaMF, una organización feminista TERF, que cuenta como una compañera de la organización hablará en la 1 sobre ‘el disparate’ de la ley.

ver_tweet_no_ley(3)
## Usuario: ConfluenciaMF
## Descripción:Confluencia estatal de organizaciones que defiende la definición de mujer basada en el sexo y se opone a toda forma de mercantilización de nuestros cuerpos.
## Contenido:Esta noche, en @La1_tve a las 21:00, la compañera @BeatrizSanJose_  explicará (si se lo permiten), la postura de la CMF ante el dislate del la #LeyTrans 
## #NoLeyTrans #SexoNoEsGénero
## Retweets:130

Cabe destacar que los tweets del hashtag #NoLeyTrans tienen muchos menos retweets que los dos otros hastags a favor.

7.4. Conclusiones de los hashtags

Hemos visto que los hashtags a favor de la ley tienen más retweets que los hashtags en contra. Esto puede indicar que la ley tiene más apoyo que detractores. Además, aunque en un principio pudiese parecer que los detractores de la ley fuesen en su mayoría votantes de derechas, parece que la mayoría es el colectivo feminista TERF.

8. Grafo de usuarios del dataset

8.1. Grafo de interacciones entre usuarios

Nuestro dataset no contiene la id de los tweets de respuesta, pero si la de los usuarios a los que se responde. Por lo tanto, crearemos un grafo de interacciones entre usuarios.

Primero, creamos un data frame con las columnas user_id y in_reply_to_user_id.

df_interacciones <- df_filtered %>%
  select(user_id, in_reply_to_user_id) %>%
  na.omit()

Creamos el grafo de interacciones.

grafo <- graph_from_data_frame(df_interacciones, directed = TRUE)

Crearemos una función para ver los usuarios con más interacciones.

# Sacamos el usuario con más interaccionesmarx
usuarios_interacciones <- degree(grafo, mode = "in")

# Creamos un data frame con los usuarios y sus interacciones
df_usuarios_interacciones_id <- data.frame(
  user_id = as.numeric(names(usuarios_interacciones)),
  interacciones = as.numeric(usuarios_interacciones))

df_usuarios_interacciones_id <- df_usuarios_interacciones_id[order(-df_usuarios_interacciones_id$interacciones),]

# Al dataframe le añadimos una columna con el nombre de usuario
df_usuarios_interacciones <- df_usuarios_interacciones_id %>%
  inner_join(df_usuarios, by = "user_id")

# Seleccionamos solo las columnas del nombre y las interacciones
df_usuarios_interacciones <- df_usuarios_interacciones %>%
  select(user_screen_name, interacciones)

head(df_usuarios_interacciones, 10)
##    user_screen_name interacciones
## 1      IreneMontero          2577
## 2              PSOE           846
## 3   sanchezcastejon           727
## 4           PODEMOS           582
## 5      carmencalvo_           544
## 6      LaEtxebarria           478
## 7    PabloEchenique           462
## 8          ierrejon           433
## 9           JMLm555           333
## 10   CarlaAntonelli           333

Vemos que los 5 usuarios más relevantes son políticos de izquierdas, lo que puede indicar que la izquierda habla más del tema que la derecha.

8.2. Usuarios con más seguidores

Creamos un data frame con los usuarios y sus seguidores.

df_usuarios_seguidores <- df_usuarios %>%
  select(user_id, user_screen_name, user_followers) %>%
  arrange(desc(user_followers))

df_usuarios_seguidores
## # A tibble: 289,380 × 3
##      user_id user_screen_name user_followers
##        <dbl> <chr>                     <int>
##  1  33884545 CNNEE                  21850774
##  2   7996082 el_pais                 8686360
##  3 236636515 lopezdoriga             8043969
##  4   9633802 ELTIEMPO                7548040
##  5 124172948 la_patilla              7454855
##  6  16676396 El_Universal_Mx         6809985
##  7 107120856 brozoxmiswebs           6651021
##  8  14834302 elespectador            6494442
##  9  25992212 todonoticias            5505632
## 10  15095537 marca                   5427385
## # ℹ 289,370 more rows

Mucho de las cuentas con más seguidores son cuentas de medios de comunicación. Aunque seán los usuarios con más seguidores, vemos que no son los usuarios con más interacciones.

9. Análisis de comunidades

Debido al tamaño y la complejidad del dataset, hemos decidido centrarnos en comunidades pequeñas pero de las cuales tenemos la certeza de que están a favor o en contra de la ley.

9.1. Generar comunidades

Al intentar analizar las comunidades mediante un algoritmo como el de Louvain, los resultados no son los esperados. Por lo tanto, utilizaremos un método más simple, que consiste en agrupar los usuarios por el contenido de su biografía.

Observando a los usuarios, vimos que es bastante común poner banderas en la descripción de los perfiles. Estas banderas, aunque no siempre tienen que ver con la opinión sobre la ley, nos sirven como punto de partida para agrupar a los usuarios.

9.1.1. Usuarios a favor

Primero, sacamos los usuarios que tienen en su descripción la bandera trans. Hemos asumido que los usuarios que tienen la bandera trans en su descripción están a favor de la ley.

Obtenemos una comunidad de 722 usuarios.

df_usuarios_favor <- df_usuarios %>%
  filter(str_detect(user_description, "🏳️‍⚧️"))
df_usuarios_favor
## # A tibble: 722 × 6
##     user_id user_screen_name user_description user_created_at_iso user_followers
##       <dbl> <chr>            <chr>            <dttm>                       <int>
##  1    13607 hober            "she/her. 🏳️‍⚧️🏳️‍🌈 @W… 2006-11-21 00:00:00           3521
##  2 10321722 sofzapatazavala  "She/Her ✸ Muje… 2007-11-17 00:00:00           1895
##  3 15451808 inaxo            "Altzatarra. Ku… 2008-07-16 00:00:00            504
##  4 16941652 nacho_w          "He/Him 🏳️‍🌈🏳️‍⚧️"    2008-10-24 00:00:00           1489
##  5 21322175 MTheLeon         "🏳️‍⚧️ (She/Her/Ell… 2009-02-19 00:00:00           1662
##  6 21427450 DANCAMPERO       "Comunicóloga o… 2009-02-20 00:00:00            899
##  7 25220784 CassieGemini     "Persona no bin… 2009-03-19 00:00:00            277
##  8 28086825 danimrlt         "Programmer of … 2009-04-01 00:00:00             53
##  9 31217555 valandres__      "Destino clande… 2009-04-14 00:00:00            570
## 10 33061864 caniculee        "Irish🇮🇪 in Mad… 2009-04-19 00:00:00            842
## # ℹ 712 more rows
## # ℹ 1 more variable: user_friends <int>

El siguiente paso será recoger todos los tweets de los usuarios a favor de la ley.

df_tweets_favor <- df_filtered %>%
  inner_join(df_usuarios_favor, by = "user_id")
9.1.2. Usuarios de vox

Sacaremos los usuarios que tengan en su descripción la palabra “vox”.

En este caso tenemos una comunidad de 369 usuarios, aproximadamente la mitad que la comunidad a favor (esto no significa que haya, en general, la mitad de usuarios en contra que a favor).

df_usuarios_vox <- df_usuarios %>%
  filter(str_detect(user_description, "vox"))
df_usuarios_vox
## # A tibble: 369 × 6
##     user_id user_screen_name user_description user_created_at_iso user_followers
##       <dbl> <chr>            <chr>            <dttm>                       <int>
##  1   4.90e7 ivanedlm         "Portavoz en el… 2009-06-20 00:00:00         324015
##  2   6.59e7 jaimeberenguer   "Digo lo que pi… 2009-08-15 00:00:00          49753
##  3   6.83e7 yiruim           "Artista del ex… 2009-08-24 00:00:00           1669
##  4   6.97e7 carvar83         "Marketero de c… 2009-08-28 00:00:00            127
##  5   8.04e7 Cheap_Movies     "Tengo las neur… 2009-10-06 00:00:00            584
##  6   8.58e7 curra01          "vox chanmartin… 2009-10-28 00:00:00           4764
##  7   9.27e7 MiguelPascual    "Secretario pro… 2009-11-26 00:00:00           1690
##  8   9.43e7 cristinapelaez   "Concejal Porta… 2009-12-03 00:00:00           8578
##  9   1.09e8 pitapulgarcit4   "\"Al final los… 2010-01-27 00:00:00          15490
## 10   1.21e8 aresauria        "IQI 👩🏽‍🔬 https:/… 2010-03-09 00:00:00            258
## # ℹ 359 more rows
## # ℹ 1 more variable: user_friends <int>

Sacamos los tweets de los usuarios en contra de la ley.

df_tweets_vox <- df_filtered %>%
  inner_join(df_usuarios_vox, by = "user_id")
9.1.3. Usuarias TERFs

Como hemos visto antes, las feministas TERFs son las que mayor oposición muestran a la ley. Ya hemos comentado antes que el termino TERF se usa de forma despectiva, hemos observado que las feministas terfs suelen denominarse así mismas como “radfem” (abreviatura de radical feminist), así que sacaremos a las usuarias que tengan en su descripción la palabra “radfem”.

df_usuarios_terf <- df_usuarios %>%
  filter(str_detect(user_description, "radfem"))
df_usuarios_terf
## # A tibble: 204 × 6
##     user_id user_screen_name user_description user_created_at_iso user_followers
##       <dbl> <chr>            <chr>            <dttm>                       <int>
##  1   2.09e7 Thornqueen       "professional l… 2009-02-15 00:00:00             49
##  2   5.01e7 Sandri_IC        "ficciones.\nra… 2009-06-23 00:00:00            231
##  3   6.49e7 blutgirl         "hembra/humana/… 2009-08-12 00:00:00           2585
##  4   9.19e7 IbtissameBetty   "Clinical Psych… 2009-11-22 00:00:00          11068
##  5   1.07e8 zorra_basica     "radfem.\nvegan… 2010-01-22 00:00:00            376
##  6   1.14e8 MayGaal          "No entres a mi… 2010-02-15 00:00:00            535
##  7   1.19e8 CarmenStonem     "Antiespecista,… 2010-03-02 00:00:00            184
##  8   1.33e8 Lady_Of_Cydonia  "#radfem #teach… 2010-04-14 00:00:00            604
##  9   1.48e8 russiandoll__    "⚢ \n\n.\n\n\n♀… 2010-05-24 00:00:00            406
## 10   1.86e8 valeriapinedam   "learning radfe… 2010-09-02 00:00:00            536
## # ℹ 194 more rows
## # ℹ 1 more variable: user_friends <int>

Sacamos los tweets de las usuarias TERFs.

df_tweets_terf <- df_filtered %>%
  inner_join(df_usuarios_terf, by = "user_id")

9.2. Palabras más frecuentes en cada comunidad

Para ver si efectivamente hemos agrupado a los usuarios correctamente, vamos a sacar las palabras más frecuentes en cada comunidad.

9.2.1. Palabras más frecuentes en la comunidad a favor

Primero, sacamos las palabras más frecuentes en la comunidad a favor de la ley.

# Creamos un corpus con los tweets
corpus_tweets_favor <- corpus(df_tweets_favor$tweet_full_text)

# Generamos los tokens
token_tweets_favor <-quanteda::tokens(corpus_tweets_favor,
                              what = "word",
                              remove_numbers = TRUE,
                              remove_punct = TRUE,
                              remove_symbols = TRUE,
                              remove_separators = TRUE,
                              remove_url = TRUE)

Creamos la matriz de frecuencia de las palabras.

# Generamos los bigramas
bigramas_favor <- tokens_ngrams(token_tweets_favor, n = 2)

# Generamos la matriz de frecuencia de los tweets
matrix_tweets_favor <-dfm(bigramas_favor)

# Vemos las 10 palabras más frecuentes
top_10 <- topfeatures(matrix_tweets_favor, 10)
top_10
##         identidad_género        derechos_personas         derechos_humanos 
##                      206                      141                       95 
##             carmen_calvo              última_hora autodeterminación_género 
##                       85                       80                       76 
##            huelga_hambre        personas_binarias           derechos_lgtbi 
##                       75                       68                       61 
##                  hoy_día 
##                       61

En la comunidad a favor de la ley aparecen bigramas como “identidad_género”, “derechos_personas”, “derechos_humanos” y “derechos_lgtbi” que reflejan una opinión positiva sobre la ley.

9.2.2. Palabras más frecuentes en la comunidad de usuarios de vox

Ahora sacamos las palabras más frecuentes en la comunidad de usuarios de vox.

# Creamos un corpus con los tweets
corpus_tweets_vox <- corpus(df_tweets_vox$tweet_full_text)

# Generamos los tokens
token_tweets_vox <-quanteda::tokens(corpus_tweets_vox,
                              what = "word",
                              remove_numbers = TRUE,
                              remove_punct = TRUE,
                              remove_symbols = TRUE,
                              remove_separators = TRUE,
                              remove_url = TRUE)

# Generamos los bigramas
bigramas_vox <- tokens_ngrams(token_tweets_vox, n = 2)

# Generamos la matriz de frecuencia de los tweets
matrix_tweets_vox <-dfm(bigramas_vox)

# Generamos el wordcloud
top_10_vox <- topfeatures(matrix_tweets_vox, 10)
top_10_vox
##       irene_montero     amenaza_mujeres       mujeres_niños santiabascal_semana 
##                 130                 106                 101                  53 
##        semana_dosis     dosis_atropello  atropello_derechos   derechos_distopía 
##                  53                  53                  53                  53 
##  distopía_sanchista  sanchista_indultos 
##                  53                  53

En la comunidad de los usuarios de vox aparecen bigramas como “amenaza_mujeres”, “derechos_distopía”, “distopía_sanchista” que reflejan una opinión negativa sobre la ley.

9.2.3. Palabras más frecuentes en la comunidad de usuarias TERFs

Por último, sacamos las palabras más frecuentes en la comunidad de usuarias TERFs.

# Creamos un corpus con los tweets
corpus_tweets_terf <- corpus(df_tweets_terf$tweet_full_text)

# Generamos los tokens
token_tweets_terf <-quanteda::tokens(corpus_tweets_terf,
                              what = "word",
                              remove_numbers = TRUE,
                              remove_punct = TRUE,
                              remove_symbols = TRUE,
                              remove_separators = TRUE,
                              remove_url = TRUE)

# Generamos los bigramas
bigramas_terf <- tokens_ngrams(token_tweets_terf, n = 2)

# Generamos la matriz de frecuencia de los tweets
matrix_tweets_terf <-dfm(bigramas_terf)

# Generamos el top 10
top_10_terf <- topfeatures(matrix_tweets_terf, 10)
top_10_terf
##           mal_llamada         irene_montero      derechos_mujeres 
##                   150                    93                    81 
## personas_transexuales          vía_urgencia             ser_mujer 
##                    57                    50                    46 
##              cada_vez      violencia_género     consejo_ministros 
##                    45                    45                    43 
##  movimiento_feminista 
##                    41

La frase “mal llamada”, se usa en muchos tweets en los que se critica la ley (“la mal llamada ley trans…”), lo mismo que “ser mujer” que son tweets en los que dicen “Quiero ser mujer, es mi derecho como hombre”. Por lo tanto se ve que las usuarias TERFs, además de hablar del feminismo y de la violencia de género, también están en contra de la ley.

9.3. Grafo de interacciones de las comunidades

Generaremos un grafo en el que los nodos verdes representarán a los usuarios en contra y los nodos morados a los usuarios a favor.

Primero, de los tweets de cada comunidad, seleccionaremos solo los tweets cuyos autores y destinatarios pertenezcan a alguna de las comunidades.

df_tweets_comunidades <- rbind(df_tweets_favor, df_tweets_vox, df_tweets_terf)

Creamos un data frame con las columnas user_id y in_reply_to_user_id de las comunidades.

df_interacciones <- df_tweets_comunidades %>%
  select(user_id, in_reply_to_user_id) %>%
  na.omit()

Creamos un grafo general con todas las interacciones. Los nodos tendrán un color distinto en función de la comunidad a la que pertenezcan. Si no pertenecen a ninguna comunidad se les asignará un color gris, si pertenecen a la comunidad a favor se les asignará un color rojo, si pertenecen a la comunidad de usuarios de vox se le asignará un color verde y si pertenecen a la comunidad de usuarias TERFs se les asignará un color morado.

grafo_comunidades <- graph_from_data_frame(df_interacciones, directed = TRUE)

# Asignamos un color a cada nodo
V(grafo_comunidades)$color <- ifelse(V(grafo_comunidades)$name %in% df_usuarios_favor$user_id, "red",
                                     ifelse(V(grafo_comunidades)$name %in% df_usuarios_vox$user_id, "green",
                                            ifelse(V(grafo_comunidades)$name %in% df_usuarios_terf$user_id, "purple", "gray")))

Por último, mostramos el grafo.

plot(
  grafo_comunidades,
  vertex.color = V(grafo_comunidades)$color,
  vertex.size = 5,
  edge.arrow.size = 0.2,
  edge.color = "gray",
  vertex.label = NA,
  main = "Grafo de interacciones de las comunidades"
)

legend("bottomright", legend = c("A favor", "Vox", "TERF", "Neutro"), fill = c("red", "green", "purple", "gray"))

Observamos que las comunidades están bastante dispersas, esto se puede deber a que en twitter predomina el “debate” y la interacción entre usuarios de distintas opiniones. Además, al ser un tema tan polarizado, es probable que muchos usuarios interactúen con usuarios de la opinión contraria.

También encontramos nodos morados y rojos que atraen a muchos nodos neutros, lo que puede indicar que las usuarias TERFs y los usuarios a favor de la ley tienen una gran influencia en la red.

10. Conclusiones

Este proyecto ha cambiado nuestra percepción sobre el fenómeno de la ley trans en España. Incialmente pensábamos que predominarían los sentimientos negativos ya que se trata de un tema muy polémico, además de que la fama de twitter es la de ser una red social en la que se comparten opiniones negativas. Sin embargo, hemos visto que los sentimientos positivos y negativos están bastante equilibrados, ganando los positivos, debido a que en el dataset analizado la ley tiene más apoyo que detractores.

Otro aspecto que nos ha sorprendido es que la mayoría de detractores de la ley son feministas TERF, y no votantes de derechas como pensábamos en un principio. Algunos de los tweets que hemos visto de las usuarias TERFs son muy agresivos y radicales, lo cual no nos esperábamos de usuarios que comparten espectro político con las personas a favor de la ley.

En general, hemos comprobado de que se trata de un tema muy pasional y polarizado, que aunque en general hay más apoyo que detractores, ambas partes tienen sus ideas muy claras y no están dispuestas a ceder.